package cnic.ai.nacos.ssh

import java.io.IOException
import java.util.concurrent.ConcurrentLinkedDeque

//import net.schmizz.sshj.common.IOUtils
//import net.schmizz.sshj.common.LoggerFactory
//import net.schmizz.sshj.common.StreamCopier
//import net.schmizz.sshj.connection.channel.direct.DirectConnection
//import net.schmizz.sshj.connection.channel.direct.Session
//import net.schmizz.sshj.connection.channel.direct.Session.Command
//import net.schmizz.sshj.connection.channel.direct.Session.Shell
//import net.schmizz.sshj.connection.channel.forwarded.ConnectListener
//import net.schmizz.sshj.connection.channel.forwarded.SocketForwardingConnectListener
//import net.schmizz.sshj.connection.channel.forwarded.X11Forwarder
//import net.schmizz.sshj.sftp.SFTPClient
//import net.schmizz.sshj.transport.verification.PromiscuousVerifier
//import net.schmizz.sshj.userauth.keyprovider.KeyPairWrapper
//import net.schmizz.sshj.userauth.keyprovider.KeyProvider
//import net.schmizz.sshj.xfer.scp.SCPFileTransfer
//
class HpcConnector
//  {
//	private var sshClient: SSHClient = SSHClient()
//	private val sshClientLock = Any()
//	private var parameter: ConnectorParameter? = null
//	private var hopQueue: ConcurrentLinkedDeque<SSHClient>? = null
//	fun getParameter(): ConnectorParameter? {
//		return parameter
//	}
//
//	fun setParameter(parameter: ConnectorParameter?) {
//		this.parameter = parameter
//	}
//
//	constructor() {}
//	constructor(parameter: ConnectorParameter?) {
//		this.parameter = parameter
//	}
//
//
//	/**
//	 * 通过parameter 连接参数
//	 * @return
//	 * @throws IOException
//	 */
//	@Throws(IOException::class)
//	fun connect(): String {
//		if (null == parameter) {
//			throw IOException("The connection parameter is invalid ! (paramter==null).")
//		}
//		return connect(parameter)
//	}
//
//	/**
//	 * 连接服务器
//	 * @param host    主机ip
//	 * @param port    端口
//	 * @param username    用户名
//	 * @param password    密码
//	 * @return
//	 * @throws IOException
//	 */
//	@Throws(IOException::class)
//	fun connect(host: String?, port: Int, username: String?, password: String?): String {
//		parameter = ConnectorParameter(host, port, username, 1, password)
//		return connect(parameter)
//	}
//
//	/**
//	 * 连接服务器
//	 * @param host    主机ip
//	 * @param port    端口
//	 * @param username    用户名
//	 * @param keyfiles    授权文件(全路径)
//	 * @return
//	 * @throws IOException
//	 */
//	@Throws(IOException::class)
//	fun connect(host: String?, port: Int, username: String?, keyfiles: Array<String?>): String {
//		parameter = ConnectorParameter(host, port, username, password=null, keyFiles = keyfiles[0])
//		return connect(parameter)
//	}
//
//	/**
//	 * 连接服务器
//	 * @param param
//	 * @return
//	 * @throws IOException
//	 */
//	@Throws(IOException::class)
//	fun connect(param: ConnectorParameter?): String {
//		synchronized(sshClientLock) {
//
//
//			//===============================================================
//			// 1. 断开连接
//			if (null != sshClient) {
//				disconnect()
//				sshClient = null
//			}
//
//			//===============================================================
//			// 2. 创建连接对象
//			sshClient = SSHClient()
//
//			//===============================================================
//			// 3. 连接服务器:[检查是否通过跳转]获取跳板再连接
//			var error: IOException? = null
//			var tryTimes = 0
//			val bTunnel =
//				null != param && null != param.getTunnelList() && param.getTunnelList().size() >= 1
//			if (bTunnel) { //  1)通过跳板链接:
//				val tunnel: DirectConnection = getDirectConnection(param, param.getTunnelList())
//				tryTimes = 0
//				while (tryTimes < TRYTIMESMAX) {
//					error = try {
//						sshClient.loadKnownHosts()
//						sshClient.setConnectTimeout(30000)
//						sshClient.connectVia(tunnel)
//						break
//					} catch (e: IOException) {
//						logger.error(
//							java.lang.String.format(
//								"Try times %d connect server[host, port, username]: [%s, %d, %s] error : %s.",
//								tryTimes + 1, param.getHost(), param.getPort(), param.getUsername(), e.message
//							)
//						)
//						e
//					}
//					++tryTimes
//				}
//			} else { // 2)直接连接服务器
//				sshClient.addHostKeyVerifier(PromiscuousVerifier())
//				sshClient.setConnectTimeout(30000)
//				tryTimes = 0
//				while (tryTimes < TRYTIMESMAX) {
//					error = try {
//						sshClient.connect(param.getHost(), param.getPort())
//						break
//					} catch (e: IOException) {
//						logger.error(
//							java.lang.String.format(
//								"Try times %d connect server[host, port, username]: [%s, %d, %s] error : %s.",
//								tryTimes + 1, param.getHost(), param.getPort(), param.getUsername(), e.message
//							)
//						)
//						e
//					}
//					++tryTimes
//				}
//			}
//			if (tryTimes >= TRYTIMESMAX) {
//				throw error!!
//			}
//
//			//===============================================================
//			// 4. 进行授权
//			auth(sshClient, param)
//		}
//
//		// 5.在服务器端执行 date命令
//		return Execute("date +%s")
//	}
//
//	/**
//	 * 授权处理
//	 * @param client
//	 * @param param
//	 * @throws IOException
//	 */
//	@Throws(IOException::class)
//	private fun auth(client: SSHClient?, param: ConnectorParameter?) {
//		val keyType: SSHKeyType = SSHKeyType.KeyType(param.getKeyType())
//		if (keyType === SSHKeyType.KEYTYPE_PUBKEY) {
//			val privateKey: String = param.getPubKey()
//			val keyProvider: KeyProvider = client.loadKeys(privateKey, null, null)
//			client.authPublickey(param.getUsername(), keyProvider)
//		} else if (keyType === SSHKeyType.KEYTYPE_KEYFILES) {
//			client.authPublickey(param.getUsername(), param.getKeyFiles())
//		} else if (keyType === SSHKeyType.KEYTYPE_PASSSWORD) {
//			client.authPassword(param.getUsername(), param.getPassword())
//		} else { // default
//			client.authPassword(param.getUsername(), param.getPassword())
//		}
//	}
//
//	/**
//	 *
//	 * @param param
//	 * @return
//	 * @throws IOException
//	 */
//	@Throws(IOException::class)
//	private fun getDirectConnection(param: ConnectorParameter?, list: List<TunnelParameter>): DirectConnection {
//		synchronized(sshClientLock) {
//
//			//===============================================================
//			// 1.创建跳板双向队列
//			if (null == hopQueue) {
//				hopQueue = ConcurrentLinkedDeque<SSHClient?>()
//			}
//
//			//===============================================================
//			// 2.建立跳板
//			if (hopQueue!!.isEmpty()) {
//				var lastHop: SSHClient? = null
//				for (tp in list) {
//					val host: String = tp.getHost()
//					val port: Int = tp.getPort()
//					val username: String = tp.getUsername()
//					val password: String = tp.getPassword()
//					var currentHop: SSHClient? = SSHClient()
//
//					// 尝试授权
//					var error: IOException? = null
//					var tryTimes = 0
//					tryTimes = 0
//					while (tryTimes < TRYTIMESMAX) {
//						error = try {
//							currentHop.loadKnownHosts()
//							if (null == lastHop) { //第一跳: 通过授权
//								currentHop.connect(host, port)
//							} else { // 非第一跳: 通过跳板
//								val lastTunnel: DirectConnection = lastHop.newDirectConnection(host, port)
//								currentHop.connectVia(lastTunnel)
//							}
//							if (StringUtils.isAllBlank(password)) {
//								currentHop.authPublickey(username)
//							} else {
//								currentHop.authPassword(username, password)
//							}
//							break
//						} catch (e: IOException) {
//							val msg = String.format(
//								"Try times %d connect server[host, port, username]: [%s, %d, %s] error : %s.",
//								tryTimes + 1, host, port, username, e.message
//							)
//							logger.error(msg)
//							e
//						}
//						++tryTimes
//					}
//					if (tryTimes >= TRYTIMESMAX) {
//						try {
//							currentHop.disconnect()
//						} catch (e: Exception) {
//							e.printStackTrace()
//						} finally {
//							currentHop.close()
//							currentHop = null
//						}
//						throw error!!
//					}
//					hopQueue!!.add(currentHop)
//					lastHop = currentHop //当前跳 变为下一跳
//				} //~for
//			} //~if
//
//			//===============================================================
//			// 3.获取最后一跳:
//			val lastHop: SSHClient? = hopQueue!!.getLast()
//
//			//===============================================================
//			// 4.建立链接:
//			return lastHop.newDirectConnection(param.getHost(), param.getPort())
//		} //~synchronized
//	}
//
//	/**
//	 * 断开连接
//	 * @return
//	 * @throws IOException
//	 */
//	@Throws(IOException::class)
//	fun disconnect(): Boolean {
//		synchronized(sshClientLock) {
//			try {
//				//===============================================================
//				// 1. 断开sshClient
//				if (null != sshClient) {
//					try {
//						if (sshClient.isConnected()) { // 只有链接才需要断开
//							sshClient.disconnect()
//						}
//					} catch (e: IOException) {
//						logger.error(e.message)
//						e.printStackTrace()
//					} catch (e: Exception) {
//						logger.error(e.message)
//						e.printStackTrace()
//					}
//				}
//
//				//===============================================================
//				// 2. 依次关闭和移除跳板
//				if (null != hopQueue) {
//					while (!hopQueue!!.isEmpty()) {
//						var currentHop: SSHClient? = null
//						try {
//							currentHop = hopQueue!!.pollLast() // 移除并返回最后添加的元素
//							if (null != currentHop) {
//								if (currentHop.isConnected()) {
//									currentHop.disconnect()
//								}
//							}
//						} catch (e: Exception) {
//							logger.error(e.message)
//							e.printStackTrace()
//						} finally {
//							if (null != currentHop) {
//								currentHop.close()
//							}
//							currentHop = null
//						}
//					}
//				}
//			} catch (ex: Exception) {
//				logger.error(ex.message)
//				ex.printStackTrace()
//			} finally {
//				//===============================================================
//				// 3. 释放资源:
//				sshClient = null // 1)释放链接
//				hopQueue = null // 2)释放跳板
//			}
//		}
//		return true
//	}
//
//	/**
//	 * 执行cd命令
//	 * @param folder
//	 * @return 返回当前目录路径
//	 * @throws IOException
//	 */
//	@Throws(IOException::class)
//	fun cdCommand(folder: String?): String {
//		val shells = String.format("cd  %s  &&  pwd  ./ ", folder)
//		return Execute(shells)
//	}
//
//	/**
//	 * 执行ls命令
//	 * @return
//	 * @throws IOException
//	 */
//	@Throws(IOException::class)
//	fun lsCommand(): List<LsCommandBean> {
//		return lsCommand(".")
//	}
//
//	/**
//	 * 执行ls命令
//	 * @param folder
//	 * @return
//	 * @throws IOException
//	 */
//	@Throws(IOException::class)
//	fun lsCommand(folder: String?): List<LsCommandBean> {
//		var folder = folder
//		if (null == folder || folder.isEmpty()) {
//			folder = "."
//		}
//		val result = Execute("ls -ll --time-style '+%Y/%m/%d %H:%M:%S' $folder")
//		return ShellCommandParser.lsCommandParser(result)
//	}
//
//	/**
//	 * 新建目录(含子目录)
//	 * @param folder 待新建的目录,如：test/ai
//	 * @return 新建目录后的全路径, 如/home/slurm/test/ai
//	 * @throws IOException
//	 */
//	@Throws(IOException::class)
//	fun mkdirCommand(folder: String?): String {
//		val shells = String.format("mkdir  -p  %s  &&  cd  %s  &&  pwd  ./ ", folder, folder)
//		return Execute(shells)
//	}
//
//	/**
//	 * 返回当前路径
//	 * @return
//	 * @throws IOException
//	 */
//	@Throws(IOException::class)
//	fun pwdCommand(): String {
//		return Execute("pwd")
//	}
//
//	/**
//	 * 执行命令
//	 * @param shell 待执行的命令
//	 * @return 返回执行Shell命令的结果，如果exitStatus!=0，则执行失败，返回error
//	 * @throws IOException
//	 */
//	@Throws(IOException::class)
//	fun Execute(shell: String?): String {
//		checkConnect()
//		return ExecutSession(shell)
//	}
//
//	/**
//	 * 执行命令
//	 * @param shell
//	 * @return
//	 * @throws IOException
//	 */
//	@Throws(IOException::class, IllegalStateException::class)
//	protected fun ExecutSession(shell: String?): String {
//		var session: Session? = null
//		return try {
//			session = sshClient.startSession()
//			val cmd: HTMLEditorSkin.Command = session.exec(shell)
//			var result: String = IOUtils.readFully(cmd.getInputStream()).toString()
//			var error: String = IOUtils.readFully(cmd.getErrorStream()).toString()
//			val exitStatus: Int = cmd.getExitStatus()
//			result = result.trim { it <= ' ' }
//			error = error.trim { it <= ' ' }
//			//logger.debug("Request: " + shell);
//			if (null != exitStatus) {
//				if (exitStatus != 0) {
//					logger.error("Error: $error, Exit Staus: $exitStatus")
//				} else {
//					logger.debug("Respone: $result, Exit Staus: $exitStatus")
//				}
//				if (exitStatus != 0 && !error.isEmpty()) {
//					return error
//				}
//			}
//			result
//		} catch (e: IOException) {
//			logger.error(e.message)
//			e.printStackTrace()
//			throw e
//		} catch (e: IllegalStateException) {
//			logger.error(e.message)
//			e.printStackTrace()
//			throw e
//		} finally {
//			try {
//				if (session != null) {
//					session.close()
//				}
//			} catch (e: IOException) {
//				// Do Nothing
//				logger.error(e.message)
//			}
//		}
//	}
//
//	/**
//	 * 执行命令
//	 * @param shell 待执行的命令
//	 * @return 返回执行Shell命令的结果，如果exitStatus!=0，则执行失败，返回error
//	 * @throws IOException
//	 */
//	@Throws(Exception::class)
//	fun ExecuteJob(shell: String?): CommandResultBean {
//		// check connect
//		try {
//			checkConnect()
//		} catch (e: IOException) {
//			e.printStackTrace()
//			logger.error(e.message)
//			throw e
//		}
//
//		// startSession
//		var session: Session? = null
//		try {
//			synchronized(sshClientLock) {
//				session = sshClient.startSession()
//				val cmd: HTMLEditorSkin.Command = session.exec(shell)
//				var result: String = IOUtils.readFully(cmd.getInputStream()).toString()
//				var error: String = IOUtils.readFully(cmd.getErrorStream()).toString()
//				val exitStatus: Int = cmd.getExitStatus()
//				result = result.trim { it <= ' ' }
//				error = error.trim { it <= ' ' }
//				//String messge = String.format("\nRequest:%s     \nExitStatus:%d        \nRespone:%s       \nError:%s \n\n",
//				//		shell, exitStatus, result, error);
//				//logger.info(messge);
//				//logger.info("\nRequest:%s\nExitStatus:%d\nRespone:%s\nError:%s\n\n", shell, exitStatus, result, error);
//				return CommandResultBean(shell, result, error, exitStatus)
//			}
//		} catch (e: IOException) {
//			e.printStackTrace()
//			logger.error(e.message)
//			throw e
//		} finally {
//			try {
//				if (session != null) {
//					session.close()
//				}
//			} catch (e: IOException) {
//				// Do Nothing
//				logger.error(e.message)
//			}
//		}
//	}
//
//	/**
//	 * 检测链接
//	 * @throws IOException
//	 */
//	@Throws(IOException::class)
//	fun checkConnect() {
//		var ret = ""
//		if (null == sshClient) { // sshClient == null
//			ret = connect()
//			return
//		}
//		synchronized(sshClientLock) {
//			if (!sshClient.isConnected()) { // sshClient.isConnected
//				try {
//					disconnect()
//				} catch (e: Exception) {
//					logger.error(e.message)
//					e.printStackTrace()
//				}
//				ret = connect()
//			} else if (!sshClient.isAuthenticated()) { // sshClient.isAuthenticated
//				try {
//					disconnect()
//				} catch (e: Exception) {
//					logger.error(e.message)
//					e.printStackTrace()
//				}
//				ret = connect()
//			} else { // sshCient isConnected and isAuthenticated
//				try {
//					ret = ExecutSession("date +%s")
//				} catch (e: Exception) {
//					e.printStackTrace()
//					try {
//						disconnect()
//					} catch (e2: Exception) {
//						val msg =
//							String.format("CheckConnect - disconnect Exception %s", e2.message)
//						logger.error(msg)
//					}
//					ret = connect()
//					logger.debug("checkConnect : $ret")
//				}
//			}
//		}
//	}
//
//	/**
//	 * 返回scpClient
//	 * @return
//	 */
//	val scpClient: SCPFileTransfer?
//		get() {
//			try {
//				checkConnect()
//			} catch (e: IOException) {
//				logger.error(e.message)
//				return null
//			}
//			return sshClient.newSCPFileTransfer()
//		}
//
//	/**
//	 * 返回sftpClient
//	 * @return
//	 * @throws IOException
//	 */
//	@get:Throws(IOException::class)
//	val sFTPClient: SFTPClient?
//		get() {
//			try {
//				checkConnect()
//			} catch (e: IOException) {
//				logger.error(e.message)
//				return null
//			}
//			return sshClient.newSFTPClient()
//		}
//
//	companion object {
//		private val logger: Logger = LogManager.getLogger()
//		private const val TRYTIMESMAX = 10 //链接尝试次数
//		@Throws(IOException::class, InterruptedException::class)
//		@JvmStatic
//		fun main(args: Array<String>) {
//			val ssh = SSHClient()
//
//			// Compression makes X11 more feasible over slower connections
//			// ssh.useCompression();
//			ssh.loadKnownHosts()
//
//			/*
//        * NOTE: Forwarding incoming X connections to localhost:6000 only works if X is started without the
//        * "-nolisten tcp" option (this is usually not the default for good reason)
//        */
//			//ssh.registerX11Forwarder(new SocketForwardingConnectListener(new InetSocketAddress("localhost", 6000)));
//			val host = "223.193.8.254"
//			val port = 22
//			val username = "ai"
//			val password = "123456"
//			ssh.connect(host, port)
//			try {
//				ssh.authPassword(username, password)
//				val sess: Session = ssh.startSession()
//
//				/*
//            * It is recommendable to send a fake cookie, and in your ConnectListener when a connection comes in replace
//            * it with the real one. But here simply one from `xauth list` is being used.
//            */
//				//sess.reqX11Forwarding("MIT-MAGIC-COOKIE-1", "b0956167c9ad8f34c8a2788878307dc9", 1);
//				sess.allocateDefaultPTY()
//				val shell: Shell = sess.startShell()
//				StreamCopier(shell.getInputStream(), System.out, LoggerFactory.DEFAULT)
//					.bufSize(shell.getLocalMaxPacketSize())
//					.spawn("stdout")
//				StreamCopier(shell.getErrorStream(), System.err, LoggerFactory.DEFAULT)
//					.bufSize(shell.getLocalMaxPacketSize())
//					.spawn("stderr")
//
//				// Now make System.in act as stdin. To exit, hit Ctrl+D (since that results in an EOF on System.in)
//				// This is kinda messy because java only allows console input after you hit return
//				// But this is just an example... a GUI app could implement a proper PTY
//				StreamCopier(System.`in`, shell.getOutputStream(), LoggerFactory.DEFAULT)
//					.bufSize(shell.getRemoteMaxPacketSize())
//					.copy()
//
//				// Wait for session & X11 channel to get closed
//				//Thread.sleep(30000);
//
//				//String result = IOUtils.readFully(shell.getInputStream()).toString();
//				//String error  = IOUtils.readFully(shell.getErrorStream()).toString();
//
//				//System.out.println(result);
//				//System.out.println(error);
//
//				//shell.close();
//				//sess.close();
//			} finally {
//				ssh.close()
//			}
//		}
//	}
//}